package com.cby.code.util;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * @author ChenBaoyang
 * @description: AppUtils
 * @date 2021/11/6 14:25
 */
public class AppUtils {
    public final static String SHA1 = "SHA1";

    /**
     * 返回一个签名的对应类型的Sha1字符串
     */
    public static String getSignInfo(Context context) {
        String packageName = context.getApplicationContext().getPackageName();
        Signature[] signs = getSignatures(context, packageName);
        String sha1 = getSignatureString(signs[0], SHA1);
        return sha1;
    }

    /**
     * 返回对应包的签名信息
     */
    public static Signature[] getSignatures(Context context, String packageName) {
        PackageInfo packageInfo = null;
        try {
            packageInfo = context.getPackageManager()
                    .getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
            return packageInfo.signatures;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取相应的类型的字符串（把签名的byte[]信息转换成16进制）
     */
    public static String getSignatureString(Signature sig, String type) {
        byte[] hexBytes = sig.toByteArray();
        String fingerprint = "error!";
        try {
            MessageDigest digest = MessageDigest.getInstance(type);
            if (digest != null) {
                byte[] digestBytes = digest.digest(hexBytes);
                StringBuilder sb = new StringBuilder();
                for (byte digestByte : digestBytes) {
                    sb.append((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3));
                }
                fingerprint = sb.toString();
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return fingerprint;
    }

    /**
     * 获取当前应用的名称
     * @param context 上下文
     * @return
     */
    public static String getAppName(Context context) {
        return getAppName(context, context.getPackageName());
    }

    /**
     * 通过包名获取该应用的名称
     * @param context  上下文
     * @param packageName 包名
     * @return
     */
    public static String getAppName(Context context, String packageName) {
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo info = manager.getPackageInfo(packageName, 0);

            // 方式一
            String name = info.applicationInfo.loadLabel(manager).toString();
            Log.i("AppUtils","name = $name");

            // 方式二
            ApplicationInfo applicationInfo = manager.getApplicationInfo(packageName, 0);
            String name2 = manager.getApplicationLabel(applicationInfo).toString();
            Log.i("AppUtils","name2 = $name2");

            return name;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取当前应用的版本号（versionCode）
     *
     * @param context  上下文
     * @return
     */
    public static Long getAppVersionCode(Context context) {
        return getAppVersionCode(context, context.getPackageName());
    }

    /**
     * 通过包名判断某个应用的版本号（versionCode）
     *
     * @param context 上下文
     * @param packageName 包名
     * @return
     */
    public static Long getAppVersionCode(Context context, String packageName) {
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo info = manager.getPackageInfo(packageName, 0);
            long versionCode;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                versionCode = info.getLongVersionCode();
            } else {
                versionCode = info.versionCode;
            }
            return versionCode;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0L;
    }

    /**
     * 获取当前应用的版本名（VersionName）
     *
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        return getVersionName(context, context.getPackageName());
    }

    /**
     * 通过包名获取某个应用的版本名（VersionName）
     *
     * @param context
     * @param packageName 包名
     * @return
     */
    public static String getVersionName(Context context, String packageName) {
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo info = manager.getPackageInfo(packageName, 0);
            return info.versionName;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 通过包名获取某个应用的图标（icon）
     * @param context
     */
    public static Bitmap getBitmap(Context context, String packageName) {
        PackageManager packageManager = null;
        ApplicationInfo applicationInfo = null;
        try {
            packageManager = context.getPackageManager();
            applicationInfo = packageManager.getApplicationInfo(
                    packageName, 0);

            // 根据自己的情况获取drawable
            Drawable d = packageManager.getApplicationIcon(applicationInfo);
            // val appIcon = packageInfo.applicationInfo.loadIcon(getPackageManager())
            BitmapDrawable bd = (BitmapDrawable) d;
            return bd.getBitmap();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 杀进程
     * @param activity
     */
    public static void killAllProcess(Activity activity){
        if(activity == null) {
            return;
        }
        Context context = activity.getApplicationContext();
        activity.finish();
        ActivityManager mActivityManager = (ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> mList = mActivityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : mList) {
            if (runningAppProcessInfo.pid != android.os.Process.myPid()) {
                android.os.Process.killProcess(runningAppProcessInfo.pid);
            }
        }

    }

    /**
     * 检测是否是有效的intent的
     * @param context 上下文
     * @return
     */
    public static boolean isValidIntent(Context context, Intent intent) {
        return context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null;
    }

    /**
     * 检测是否有安装指定包名的包
     * @param context
     * @param pkgName
     * @return
     */
    public static boolean hasPackage(Context context, String pkgName) {
        if (TextUtils.isEmpty(pkgName)) {
            return false;
        }
        PackageInfo packageInfo = null;
        try {
            packageInfo = context.getPackageManager().getPackageInfo(pkgName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            // 抛出找不到的异常，说明该程序已经被卸载
        }
        return packageInfo != null;
    }

    /**
     * 检测是否有安装指定包名的包
     * @param context      上下文
     * @param packageName  指定要检测的包名
     * @return
     */
    public static boolean checkInstallPackageExist(Context context, String packageName) {
        if(TextUtils.isEmpty(packageName)) {
            return false;
        }
        // 获取PackageManager
        final PackageManager packageManager = context.getPackageManager();
        // 获取所有已安装程序的包信息
        List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
        if (packageInfoList != null) {
            for (int i = 0; i < packageInfoList.size(); i++) {
                String pn = packageInfoList.get(i).packageName;
                if (pn.equals(packageName)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Apk包安装
     * @param activity
     * @param apkFile
     */
    public static void installApk(Activity activity, File apkFile) {

        ShellUtils.execCmd("chmod 777 " + apkFile.getAbsolutePath(), false);

        Context appContext = activity.getApplicationContext();

        PackageManager packageManager = appContext.getPackageManager();

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //表明不是未知来源
        intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);

        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            uri = FileProvider.getUriForFile(appContext,
                    appContext.getPackageName() + ".fileprovider",
                    apkFile);
            //兼容8.0
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                boolean hasInstallPermission = packageManager.canRequestPackageInstalls();
                if (!hasInstallPermission) {
                    //请求安装未知应用来源的权限
                    /*  ActivityCompat.requestPermissions(activity, new String[]{
                        Manifest.permission.REQUEST_INSTALL_PACKAGES}, 6666);*/

                    List<ResolveInfo> resolveLists = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
                    // 查询所有符合 intent 跳转目标应用类型的应用，注意此方法必须放置在 setDataAndType 方法之后
                    // 然后全部授权
                    for (ResolveInfo resolveInfo : resolveLists){
                        String packageName = resolveInfo.activityInfo.packageName;
                        appContext.grantUriPermission(packageName,
                                uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    }
                }
            }
        } else {
            uri = Uri.fromFile(apkFile);

        }

        intent.setDataAndType(uri,
                "application/vnd.android.package-archive");


        if (packageManager.queryIntentActivities(intent, 0)
                .size() > 0) {

            activity.startActivity(intent);
        }
    }
}
